package com.example.designpatten.chapter7_proxypatten;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxy {
    /*动态代理对象不需要实现接口，但是要求目标对象必须实现接口，否则不能使用动态代理。*/
    public static void main(String[] args) {
        IUserDao target = new UserDao();
        //输出目标对象信息
        System.out.println(target.getClass());
        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
        //输出代理对象信息
        System.out.println(proxy.getClass());
        //执行代理方法
        proxy.save("xxxxxxxxxxxx");
    }

    /*接口类*/
    interface IUserDao {
        void save(String para);
    }

    static class UserDao implements IUserDao {
        @Override
        public void save(String para) {
            System.out.println("保存数据" + para);
        }
    }

    /*
    * java.lang.reflect Proxy，主要方法为
static Object    newProxyInstance(ClassLoader loader,  //指定当前目标对象使用类加载器

 Class<?>[] interfaces,    //目标对象实现的接口的类型
 InvocationHandler h      //事件处理器
)
//返回一个指定接口的代理类实例，该接口可以将方法调用指派到指定的调用处理程序。
java.lang.reflect InvocationHandler，主要方法为
 Object    invoke(Object proxy, Method method, Object[] args)
// 在代理实例上处理方法调用并返回结果。
    * */
    static class ProxyFactory {
        // 维护一个目标对象
        private Object target;

        public ProxyFactory(Object target) {
            this.target = target;
        }

        public Object getProxyInstance() {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("开启事务");
                            // 执行目标对象方法
                            Object returnValue = method.invoke(target, args);
                            System.out.println("提交事务");
                            return null;
                        }
                    });
        }
    }
}
